using BasicData.Domain.Entities;
using BasicData.Infrastructure.Emplment;
using BasicData.Infrastructure.Interfasce;
using BasicData.Infrasturctrue;
using BasicData.API.Services;
using BasicData.API.Application.Mediator;
using Microsoft.EntityFrameworkCore;
using System.Reflection;
using System.Text.Json.Serialization;
using Microsoft.OpenApi.Models;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using System.Text;
using System.Threading.Tasks;
using System.IdentityModel.Tokens.Jwt;
using OfficeOpenXml;

namespace BasicData.API
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var builder = WebApplication.CreateBuilder(args);

            // Add services to the container.

            builder.Services.AddControllers();
            // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
            builder.Services.AddEndpointsApiExplorer();
            //文档注释
            builder.Services.AddSwaggerGen(s =>
            {
                //jwt鉴权在swagger中的应用
                s.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme()
                {
                    Description = "在下框中输入请求头中需要添加Jwt授权Token：Bearer Token",
                    Name = "Authorization",
                    In = ParameterLocation.Header,
                    Type = SecuritySchemeType.ApiKey,
                    BearerFormat = "JWT",
                    Scheme = "Bearer"
                });
                s.AddSecurityRequirement(new OpenApiSecurityRequirement
    {
        {
            new OpenApiSecurityScheme
            {
                Reference = new OpenApiReference
                {
                    Type = ReferenceType.SecurityScheme,
                    Id = "Bearer"
                }
            },
            new string[] { }
        }
    });
                //xmlĵע
                var file = Path.Combine(AppContext.BaseDirectory, "BasicData.API.xml");
                var file1 = Path.Combine(AppContext.BaseDirectory, "BasicData.Domain.xml");
                var file2 = Path.Combine(AppContext.BaseDirectory, "BasicData.ErrorCode.xml");
                var file3 = Path.Combine(AppContext.BaseDirectory, "BasicData.Infrastructure.xml");
                s.IncludeXmlComments(file, true);
                s.IncludeXmlComments(file1, true);
                s.IncludeXmlComments(file2, true);
                s.IncludeXmlComments(file3, true);
            });

            //验证码缓存
            builder.Services.AddMemoryCache();
            
            //MediatR
            builder.Services.AddMediatR(cfg => cfg.RegisterServicesFromAssembly(Assembly.GetExecutingAssembly()));
            
            //依赖注入
            builder.Services.AddScoped(typeof(IBaseRepositroy<>), typeof(BaseRepositroy<>));
            builder.Services.AddScoped<IUserMediator, UserMediator>();
            builder.Services.AddScoped<IProductionInfoMediator, ProductionInfoMediator>();
            builder.Services.AddScoped<IGoodsMediator, GoodsMediator>();
            builder.Services.AddScoped<RedisHelper>();
            builder.Services.AddScoped<RedisCacheService>();
            builder.Services.AddScoped<ICaptchaService, RedisCaptchaService>(); // 使用基于Redis的验证码服务
            builder.Services.AddScoped<JwtHelper>();
            
            //跨域
            builder.Services.AddCors(options =>
            {
                options.AddPolicy("AllowAll", policy =>
                {
                    policy.SetIsOriginAllowed(_ => true)   // 允许任何来源
                          .AllowAnyMethod()               // 允许任何HTTP方法
                          .AllowAnyHeader()               // 允许任何HTTP头
                          .AllowCredentials()             // 允许凭证（cookies等）
                          .WithExposedHeaders("Token-Expired", "Content-Disposition"); // 允许这些响应头被前端访问
                });
            });
            
            //添加JWT身份验证服务
            builder.Services.AddAuthentication(options =>
            {
                options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
                options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
            })
            .AddJwtBearer(options =>
            {
                options.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuer = true,
                    ValidateAudience = true,
                    ValidateLifetime = true,
                    ValidateIssuerSigningKey = true,
                    ValidIssuer = builder.Configuration["Jwt:Issuer"],
                    ValidAudience = builder.Configuration["Jwt:Audience"],
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Jwt:SecretKey"]))
                };
                
                // 添加事件处理
                options.Events = new JwtBearerEvents
                {
                    OnAuthenticationFailed = context =>
                    {
                        if (context.Exception is SecurityTokenExpiredException)
                        {
                            context.Response.Headers.Add("Token-Expired", "true");
                        }
                        Console.WriteLine($"JWT认证失败: {context.Exception?.Message}");
                        return Task.CompletedTask;
                    },
                    OnChallenge = context =>
                    {
                        // 跳过默认的处理
                        context.HandleResponse();

                        context.Response.StatusCode = 401;
                        context.Response.ContentType = "application/json";
                        
                        var result = System.Text.Json.JsonSerializer.Serialize(new
                        {
                            Code = 401,
                            Message = "未授权访问，请提供有效的认证令牌"
                        });
                        
                        return context.Response.WriteAsync(result);
                    }
                };
            });
            
            //连接字符串
            var connectionString = builder.Configuration.GetConnectionString("ConStr");

            //数据库上下文
            builder.Services.AddDbContext<MyDbContext>(options => options.UseSqlServer(connectionString));

            var app = builder.Build();

            // Configure the HTTP request pipeline.
            if (app.Environment.IsDevelopment())
            {
                app.UseSwagger();
                app.UseSwaggerUI();
            }

            // 启用静态文件服务
            app.UseStaticFiles();

            // 配置路由
            app.UseRouting();

            // 配置CORS
            app.UseCors("AllowAll");

            // 配置认证和授权
            app.UseAuthentication();
            app.UseAuthorization();

            // 配置终结点
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });

            app.Run();
        }
    }
}

